#ifndef CONF_READER_H
#define CONF_READER_H

#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <map>
#include <algorithm>

using namespace std;


struct ConfReader {

	static bool isSpace(unsigned char c) {
		return (c == ' ' || c == '\n' || c == '\r' ||
				c == '\t' || c == '\v' || c == '\f');
	};

	ConfReader() {};

	std::map<string, string> params;

	void read_config(const char* fname) {
		
		string str;

		ifstream In(fname);
		vector<string> v;
	
		string prefix = "";
		while ( ! In.eof() ) {
			getline (In, str);
			str.erase(std::remove_if(str.begin(), str.end(), isSpace), str.end());
			int cage;
			if((cage = str.find('#')) != string::npos)
				str.erase(cage);
			if(str[0] == '[')
				prefix = str.substr(1, str.find(']')-1);
			else if(!str.empty() && str[0] != '#')
				v.push_back(prefix + "_" + str);
		};

		for(int i=0; i<v.size(); i++)
			params.insert(std::make_pair(v[i].substr(0, v[i].find('=')), v[i].substr(v[i].find('=')+1) ));
	
	    for(int i=0; i<v.size(); i++)
	    	cout << i+1 << " string is \"" << v[i] << "\"" << endl;

		std::map<string, string>::iterator it = params.begin();
		while(it != params.end()) {
			cout << "\'" << it->first << "\' -> \'" << it->second << "\'" << endl;
			it++;   
		};
	
	};

	void splitStr(string& str, std::vector<string>& parts) {
		int d=0, old_d = 0;
		while((d = str.find(',', old_d)) != string::npos) {
			parts.push_back(str.substr(old_d, d-old_d));
			old_d = d+1;
		};
		parts.push_back(str.substr(old_d));
	};

	void getInts(string& key, std::vector<int>& res) {
		string s = params[key];
		std::vector<string> args;
		splitStr(s, args);
		for(int i=0; i<args.size(); i++)
			res.push_back(std::stoi(args[i]));
	};

	void getString(string& key, string& res) {
		res = params[key];
	};

	void getDoubles(string& key, std::vector<double>& res) {
		string s = params[key];
		std::vector<string> args;
		splitStr(s, args);
		for(int i=0; i<args.size(); i++)
			res.push_back(std::stod(args[i]));
	};
};

#endif
